﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace Mbs.Net
{
    public interface IServiceSender : IServiceHandler
    {
        void Send(byte[] packet);
    }

    public interface IPacketServiceSender : IServiceSender
    {
        ICoding Coding { get; }
        void Send(IPacket packt);
    }

    public class ServiceSender : ServiceHandler, IServiceSender
    {

        public virtual void Send(byte[] data)
        {
            if (!Socket.Connected)
            {
                OnExceptionFired(new NetException(SocketError.NotConnected));
                return;
            }

            if (data != null && data.Length > 0)
            {
                int length = data.Length + Info.PacketSeparateFlag.Length;
                var bytes = new byte[length];

                data.CopyTo(bytes, 0);
                Info.PacketSeparateFlag.CopyTo(bytes, data.Length);

                try
                {
                    Socket.BeginSend(bytes, 0, length, SocketFlags.None, ar =>
                    {
                        try
                        {
                            Socket.EndSend(ar);
                        }
                        catch (Exception ex)
                        {
                            OnExceptionFired(ex);
                            Host.Close();
                        }
                    }, null);
                }
                catch (Exception ex)
                {
                    OnExceptionFired(ex);
                    Host.Close();
                }
            }
        }

        
    }

    public class PacketServiceSender : IPacketServiceSender
    {
        private IServiceSender ByteSender;
        public ICoding Coding { get; set; }

        public PacketServiceSender(IServiceSender byteSender)
        {
            ByteSender = byteSender;
        }

        protected virtual void OnInit() { }

        #region IPacketServiceSender Members

        public void Send(IPacket packt)
        {
            if (packt == null)
                throw new ArgumentNullException("packt");

            ByteSender.Send(Coding.EncodePacket(packt));
        }

        #endregion

        #region IServiceSender Members

        public void Send(byte[] packet)
        {
            ByteSender.Send(packet);
        }

        #endregion

        #region IServiceHandler Members

        public Mbs.Net.Tcp.HostInfo Info
        {
            get { return ByteSender.Info; }
        }

        public IServiceHost Host
        {
            get { return ByteSender.Host; }
        }

        public void Init(Mbs.Net.Tcp.HostInfo info, IServiceHost host, Socket socket)
        {
            if (Coding == null)
                throw new NullReferenceException("Coding");

            ByteSender.Init(info, host, socket);

            OnInit();
        }

        #endregion
    }

   
}
